package com.bjpowernode.mvc.controller;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.StrUtil;
import com.bjpowernode.common.client.DfsClient;
import com.bjpowernode.common.enums.RespCode;
import com.bjpowernode.mvc.model.dto.DeleteFileDTO;
import com.bjpowernode.mvc.model.dto.SaveHeaderImageDTO;
import com.bjpowernode.mvc.model.dto.UploadFileDTO;
import com.bjpowernode.mvc.model.result.CommonResult;
import com.bjpowernode.mvc.service.inter.UploadFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;


/**
 * 文件上传
 */
@Slf4j
@RequiredArgsConstructor
@RestController
public class UploadFileController {

    private final UploadFileService uploadFileService;

    //存储要删除的FastDFS中的文件数据
    private List<DeleteFileDTO> deleteFileDTOList;

    /**
     * 头像文件上传
     *
     * @param headerFile
     * @return
     */
    @PostMapping("/upload/header")
    public CommonResult uploadFile(@RequestParam("headerFile") MultipartFile headerFile,
                                   @RequestHeader("uid") Integer uid) {
        try {
            deleteFileDTOList = new ArrayList<>();
            //1、判断是否上传文件
            //不能使用headerFile == null来判断，无效
            //原因：MultipartFile这个对象，无论有没有文件进行上传，框架都会创建这个对象
            if (headerFile.isEmpty()) {
                //没有上传文件,请上传文件
                return CommonResult.warn(RespCode.UPLOAD_FILE_EMPTY);
            }

            //2、判断文件类型、扩展名   使用hutool工具库判断
            String type = FileTypeUtil.getType(headerFile.getInputStream());
            if (!("png".equals(type) || "gif".equals(type) || "jpg".equals(type))) {
                //文件类型不允许
                return CommonResult.warn(RespCode.UPLOAD_TYPE_ERR);
            }

            //3、文件的宽高   把上传后的文件读取到内存中，在内存中读取文件的宽高
            BufferedImage image = ImageIO.read(headerFile.getInputStream());
            //文件的高
            int height = image.getHeight();
            //文件的宽
            int width = image.getWidth();
            if (height > 300 || width > 300) {
                //头像文件应小于300*300！
                return CommonResult.warn(RespCode.UPLOAD_W_H_ERR);
            }

            //4.文件大小
            long size = headerFile.getSize();
            if (size > 1024 * 1024) {
                //头像不能超过1M
                return CommonResult.warn(RespCode.UPLOAD_W_H_ERR);
            }

            //5、上传头像(FastDFS)
            UploadFileDTO uploadFileDTO = new UploadFileDTO();
            //文件后缀
            uploadFileDTO.setExt(type);
            //用户ID
            uploadFileDTO.setUid(uid);
            //文件内容
            uploadFileDTO.setContent(headerFile.getBytes());
            //文件宽
            uploadFileDTO.setWidth(width);
            //文件高
            uploadFileDTO.setHeight(height);
            //上传头像到FastDFS
            uploadFileService.uploadFileDFS(uploadFileDTO);

            //6、判断是否上传成功(FastDFS)
            if (StrUtil.isEmpty(uploadFileDTO.getGroup()) || StrUtil.isEmpty(uploadFileDTO.getFieldId())) {
                return CommonResult.warn(RespCode.UPLOAD_FILE_ERR);
            }
            //存储要删除的FastDFS中的文件数据
            deleteFileDTOList.add(new DeleteFileDTO(uploadFileDTO.getGroup(), uploadFileDTO.getFieldId()));

            //7、存储文件信息(mySQL)
            SaveHeaderImageDTO saveHeaderImageDTO = uploadFileService.insertOrUploadFile(uploadFileDTO);
            if (saveHeaderImageDTO.getResult().equals(RespCode.OK.name())) {
                //从待删除列表中移除
                deleteFileDTOList.remove(0);

                //如果saveHeaderImageDTO.getGroup()不为空，说明有旧的头像需要删除
                if (StrUtil.isNotEmpty(saveHeaderImageDTO.getGroup())) {
                    //存储要删除的FastDFS中的文件数据
                    deleteFileDTOList.add(new DeleteFileDTO(saveHeaderImageDTO.getGroup(), saveHeaderImageDTO.getFieldId()));
                }
            } else {
                //头像保存失败，请稍后重试
                return CommonResult.warn(RespCode.UPLOAD_FILE_SAVE_ERR);
            }

            //返回上传的文件的nginx访问的url的地址
            //http://192.168.72.128:8888/group1/M00/00/00/wKhIgGU1ytOARi_nAAA14oZb6JQ592.jpg
            String httpUrl = DfsClient.HTTP_URL + uploadFileDTO.getGroup() + "/" + uploadFileDTO.getFieldId();
            return CommonResult.ok(httpUrl);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //8、对原有的FastDFS中的文件进行删除操作
            deleteFileDTOList.forEach(deleteFileDTO -> {
                int result = uploadFileService.deleteFileDFS(deleteFileDTO.getGroup(), deleteFileDTO.getFileId());
                log.info("DFS删除文件group-{},fileId-{},删除的结果-{}", deleteFileDTO.getGroup(), deleteFileDTO.getFileId(), result);
            });
        }
        return CommonResult.warn(RespCode.FAIL);
    }
}
